programming4us
           
 
 
Programming

jQuery 1.3 : Developing plugins - Method parameters

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
11/24/2010 9:13:19 AM
We've now seen several examples of plugin methods, some of which take explicit parameters, and some of which do not. As we have explored, the keyword this is always available to provide context for the method, but we can also supply additional information to influence the method's operation. So far, the parameters have been few, but of course this list could grow large. There are several tricks we can use to manage our method parameters and make life easier for those using our plugins.

As our example, we'll start with a plugin method that provides a shadow on a block of text. Our technique will be similar to that used for the fading effect on the news rotator : we will use a number of elements that are partially transparent, overlaid in different positions on the page.

jQuery.fn.shadow = function() {
return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < 5; i++) {
$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left + i,
top: $originalElement.offset().top + i,
margin: 0,
zIndex: -1,
opacity: 0.1
})
.appendTo('body');
}
});
};

For each element this method is called on, we make a number of clones of the element, adjusting their opacity. These clones are positioned absolutely, at varying offsets from the original element.

As usual, we'll test our plugin using some simple HTML:

<body>
<h1>The quick brown fox jumps over the lazy dog.</h1>
</body>

For the moment, our plugin takes no parameters, so calling the method is simple:

$(document).ready(function() {
$('h1').shadow();
});

Simple parameters

Now we can introduce some flexibility to the plugin method. The operation of the method relies on several numeric values that the user might want to modify. We can make these into parameters so they can be changed on demand.

jQuery.fn.shadow = function(slices, opacity, zIndex) {

return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < slices; i++) {

$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left + i,
top: $originalElement.offset().top + i,
margin: 0,
zIndex: zIndex,
opacity: opacity

})
.appendTo('body');
}
});
};

Now, when calling our method, we must provide these three values.

$(document).ready(function() {
$('h1').shadow(10, 0.1, -1);
});

Our new parameters work as anticipated&mdash;the shadow is longer, using twice as many slices as before&mdash;but the method interface is less than ideal. These three numbers are easily confused, and their order cannot be logically deduced. It would be an improvement to label the parameters, for the benefit of both the person writing the method call, and anyone who later wishes to read and interpret it.

Parameter maps

We have seen many examples in the jQuery API of maps being provided as method parameters. This can be a much friendlier way to expose options to a plugin user than the simple parameter list we just used. A map provides a visual label for each parameter, and also makes the order of the parameters irrelevant. In addition, any time we can mimic the jQuery API in our plugins, we should do so to increase consistency and therefore ease-of-use.

jQuery.fn.shadow = function(opts) {

return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < opts.slices; i++) {

$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left + i,
top: $originalElement.offset().top + i,
margin: 0,
zIndex: opts.zIndex,
opacity: opts.opacity

})
.appendTo('body');
}
});
};

All we have changed to enable our new interface is the way each parameter is referenced; instead of having a separate variable name, each value is accessed as a property of the opts argument to the function.

Calling this method now requires a map of values rather than three individual numbers:

$(document).ready(function() {
$('h1').shadow({
slices: 5,
opacity: 0.25,
zIndex: -1
});
});

The purpose of each parameter is now obvious from a quick glance at the method call.

Default parameter values

As the number of parameters for a method grows, it becomes less likely that we will always want to specify each one. A sensible set of default values can make a plugin interface much more usable. Fortunately, using a map for our parameters helps with this task as well; it is simple to omit any item from the map and replace it with a default.

jQuery.fn.shadow = function(options) {
var defaults = {
slices: 5,
opacity: 0.1,
zIndex: -1
};
var opts = jQuery.extend(defaults, options);

return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < opts.slices; i++) {
$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left + i,
top: $originalElement.offset().top + i,
margin: 0,
zIndex: opts.zIndex,
opacity: opts.opacity
})
.appendTo('body');
}
});
};


Here, we have defined a new map, called defaults, within our method definition. The utility function $.extend() lets us take the options map provided as an argument and use it to override the items in defaults, leaving omitted items alone.

We still call our method using a map, but now we can specify only the parameters that we want to differ from their defaults:

$(document).ready(function() {
$('h1').shadow({
opacity: 0.05
});
});

Unspecified parameters use their default values. The $.extend() method even accepts null values, so if the default parameters are all acceptable, our method can be called very simply without errors:

$(document).ready(function() {
$('h1').shadow();
});

Callback functions

Of course, some method parameters can be quite a bit more complicated than a simple numeric value. One common parameter type we have seen frequently throughout the jQuery API is the callback function. Callback functions can lend a large amount of flexibility to a plugin without requiring a great deal of preparation when creating the plugin.

To employ a callback function in our method, we need simply accept the function object as a parameter and call that function where appropriate in our method implementation. As an example, we can extend our text shadow method to allow the user to customize the position of the shadow relative to the text.

jQuery.fn.shadow = function(options) {
var defaults = {
slices: 5,
opacity: 0.1,
zIndex: -1,
sliceOffset: function(i) {
return {x: i, y: i};

}
};
var opts = jQuery.extend(defaults, options);
return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < opts.slices; i++) {
var offset = opts.sliceOffset(i);

$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left
+ offset.x,
top: $originalElement.offset().top
+ offset.y,

margin: 0,
zIndex: opts.zIndex,
opacity: opts.opacity
})
.appendTo('body');
}
});
};


Each slice of the shadow has a different offset from the original text. Before, this offset has simply been equal to the index of the slice. Now, though, we're calculating the offset using the sliceOffset() function, which is a parameter that the user can override. So, for example, we could provide negative values for the offset in both dimensions:
$(document).ready(function() {
method parameterscall-back function$('h1').shadow({
sliceOffset: function(i) {
return {x: -i, y: -2*i};
}
});
});

This will cause the shadow to be cast up and to the left rather than down and to the right:

The callback allows simple modifications to the shadow's direction, or much more sophisticated positioning if the plugin user supplies the appropriate callback. If the callback is not specified, then the default behavior is once again used.

Customizable defaults

We can improve the experience of using our plugins by providing reasonable default values for our method parameters, as we have seen. However, sometimes it can be difficult to predict what a reasonable default value will be. If a script will be calling our plugin multiple times with a different set of parameters than we set as the defaults, the ability to customize these defaults could significantly reduce the amount of code that needs to be written.

To make the defaults customizable, we need to move them out of our method definition and into a location that is accessible by outside code:

jQuery.fn.shadow = function(options) {
var opts = jQuery.extend({},
jQuery.fn.shadow.defaults, options);

return this.each(function() {
var $originalElement = jQuery(this);
for (var i = 0; i < opts.slices; i++) {
var offset = opts.sliceOffset(i);
$originalElement
.clone()
.css({
position: 'absolute',
left: $originalElement.offset().left + offset.x,
top: $originalElement.offset().top + offset.y,
margin: 0,
zIndex: opts.zIndex,
opacity: opts.opacity
})
.appendTo('body');
}
});
};
jQuery.fn.shadow.defaults = {
slices: 5,
opacity: 0.1,
zIndex: -1,
sliceOffset: function(i) {
return {x: i, y: i};
}
};



The defaults are now in the namespace of the shadow plugin, and can be directly referred to with $.fn.shadow.defaults. Our call to $.extend() had to change to accommodate this as well. Since we are now reusing the same defaults map for every call to .shadow(), we can't allow $.extend() to modify it. Instead, we provide an empty map {} as the first argument to $.extend(), and it is this new object that gets modified.

Now code that uses our plugin can change the defaults that all subsequent calls to .shadow() will use. Options can also still be supplied at the time the method is invoked.

$(document).ready(function() {
$.fn.shadow.defaults.slices = 10;
$('h1').shadow({
sliceOffset: function(i) {
return {x: -i, y: i};
}
});
});

This script will create a shadow with 10 slices, because that is the new default value, but will also cast the shadow left and down, due to the sliceOffset callback that is provided along with the method call.

Other -----------------
- The LINQ Set Operators
- iPhone 3D Programming : Vertices and Touch Points - Creating a Wireframe Viewer (part 3)
- iPhone 3D Programming : Vertices and Touch Points - Creating a Wireframe Viewer (part 2)
- iPhone 3D Programming : Vertices and Touch Points - Creating a Wireframe Viewer (part 1)
- iPhone 3D Programming : Vertices and Touch Points - Boosting Performance with Vertex Buffer Objects
- iPhone 3D Programming : Vertices and Touch Points - Saving Memory with Vertex Indexing
- iPhone 3D Programming : Vertices and Touch Points - Reading the Touchscreen
- iPhone 3D Programming : HelloCone with Shaders
- Search Engine Basics : Country-Specific Search Engines
- Search Engine Basics : Vertical Search Engines
- Building Android Apps : Animation - Adding the Settings Panel
- Building Android Apps : Animation - Adding the New Entry Panel
- Building Android Apps : Animation - Adding the Date Panel
- Building Android Apps : Animation - Adding the Dates Panel
- Building Android Apps : Animation - Sliding Home
- Programming Windows Azure : Understanding the Value of Queues
- Programming Windows Azure : Table Operations - Deleting Tables, Deleting Entities
- Programming Windows Azure : Table Operations - Updating Entities
- Programming Windows Azure : Table Operations - Understanding Pagination
- Programming Windows Azure : Table Operations - Using Partitioning
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us